package com.atguigu.srb.core.task;

import com.atguigu.srb.base.consts.SrbMqConst;
import com.atguigu.srb.base.dto.SmsDTO;
import com.atguigu.srb.core.pojo.entity.Borrower;
import com.atguigu.srb.core.pojo.entity.LendReturn;
import com.atguigu.srb.core.pojo.entity.UserInfo;
import com.atguigu.srb.core.service.BorrowerService;
import com.atguigu.srb.core.service.DictService;
import com.atguigu.srb.core.service.LendReturnService;
import com.atguigu.srb.core.service.UserInfoService;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.joda.time.DateTime;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

//定时任务
@Component
public class SrbTask {
    @Resource
    LendReturnService lendReturnService;
    @Resource
    UserInfoService userInfoService;
    @Resource
    RabbitTemplate rabbitTemplate;
    @Resource
    BorrowerService borrowerService;
    @Resource
    DictService dictService;
    @Resource
    RedisTemplate redisTemplate;
    //每天早上8点 轮询判断如果有用户需要还款 发送还款通知
    //cron表达式： springtask支持6位的表达式
    // 完整的cron表达式有7位： 秒、分、时、日、月、周、年   xxljob的管理系统直接可以选择配置生成
    //每过5秒执行一次定时任务
//    @Scheduled(cron = "*/5 * * * * ?") //绑定一个方法 创建定时任务
//    @Scheduled(cron = "0/20 * 14 * * ?") //绑定一个方法 创建定时任务
    @Scheduled(cron = "0 0 8 * * ?") //绑定一个方法 创建定时任务
    public void returnAmountTask(){
//        System.out.println("任务执行时间："+new Date());

        //查询需要通知的还款列表
        List<LendReturn> lendReturns = lendReturnService.list(Wrappers.lambdaQuery(LendReturn.class)
                .eq(LendReturn::getStatus, 0)
                //如果用户还款日期小于等于 今天+1   提前一天通知
                .le(LendReturn::getReturnDate, new DateTime()
                        .plusDays(1).toString("yyyy-MM-dd")));//2023-4-17  2023 4 18
        //如果以上集合为空结束定时任务
        if(CollectionUtils.isEmpty(lendReturns)){
            return;
        }
        //遍历为每个用户发消息通知还款
        lendReturns.forEach(lendReturn -> {
            UserInfo userInfo = userInfoService.getById( lendReturn.getUserId());
            SmsDTO smsDto = new SmsDTO();
            smsDto.setType(5);
            smsDto.setMobile(userInfo.getMobile());
            smsDto.setParams(Arrays.asList("hq"));
            rabbitTemplate.convertAndSend(SrbMqConst.SMS_EXCHANGE,
                    SrbMqConst.SMS_ROUTING_KEY,
                    smsDto);

        });



    }

    //定时任务：在访问量较小时生成统计数据保存
    @Scheduled(cron="*/30 * * * * ?")
//    @Scheduled(cron="0 0 3 * * ?")
    public void generateStatistics(){
        //生成的数据一般保存到 数据库
        //  统计分析表： id  生成统计的日期  统计数据的日期  统计数据列表   更新时间 逻辑删除
        //暂时存到redis中:统计注册用户的学历、收入
        List<Borrower> borrowers = borrowerService.list();

        //统计每个学历的人数、每个收入的人数存到redis中
        //使用Education的值分组，相同的Education属性值的Borrower对象存到一个List集合中，使用Education的值作为键再存到map中
        Map<Integer, List<Borrower>> educationMap =
                borrowers.stream()
                .collect(Collectors.groupingBy(borrower -> borrower.getEducation()));
        //  大专  2   本科 5   硕士 1
        Map<String,Integer> educations = new HashMap<>();
        educationMap.forEach((k,v)->{
            String name = dictService.getDictNameByDictCodeAndValue("education", k);
            educations.put(name,v.size());
        });
        Map<Integer, List<Borrower>> incomeMap = borrowers.stream()
                .collect(Collectors.groupingBy(borrower -> borrower.getIncome()));

        Map<String,Integer> incomes = new HashMap<>();
        incomeMap.forEach((k,v)->{
            String name = dictService.getDictNameByDictCodeAndValue("income", k);
            incomes.put(name,v.size());
        });


        redisTemplate.opsForValue().set("stat:educations",educations);
        redisTemplate.opsForValue().set("stat:incomes",incomes);
    }
}
